package com.example.service.impl;

import com.example.anno.Log;
import com.example.mapper.UserMapper;
import com.example.pojo.PageBean;
import com.example.pojo.Result;
import com.example.pojo.User;
import com.example.properties.SystemProperties;
import com.example.service.UserService;
import com.example.utils.CheckUtil;
import com.example.utils.CryptoUtil;
import com.example.utils.SaltAESUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private SystemProperties sysConf;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisService redisService;

    @Override
    public User getById(Integer userID) {
        User user = userMapper.getByID(userID);
        //加密用户的身份证号，设置密码跟salt为空再返还给前端
        String idNumberEncrypt = CryptoUtil.encryptEasy(user.getIdNumber(), sysConf.getCKey());
        user.setIdNumber(idNumberEncrypt);
        user.setSalt(null).setPassword(null);
        return user;
    }

    @Log
    @Override
    public void delete(List<Integer> userIDs) {
        userMapper.deleteByIDs(userIDs);
    }

    //新增用户
    @Override
    public Result save(User user) {
        // 解密身份证号
        String idNumber = CryptoUtil.desEncrypt(user.getIdNumber(), sysConf.getCKey(), user.getIv());
        if (StringUtils.isBlank(idNumber)) {
            return Result.error("身份证号无效！");
        }
        // 检验身份证是否已注册
        User userByIdNumber = userMapper.selectUserByIdNumber(idNumber);
        if (userByIdNumber != null) {
            return Result.error("身份证号已被注册");
        }
        boolean b1 = CheckUtil.isValidPhoneNumber(user.getPhoneNumber());
        boolean b2 = CheckUtil.isValidIdCard(idNumber);
        if(!(b1&&b2)){
            return Result.error("身份证或手机号码错误");
        }
        // 检查验证码
        Object yzm = redisService.get(user.getPhoneNumber());
        if (yzm == null) {
            return Result.error("验证码已失效，请重新获取验证码");
        }
        if (!StringUtils.equals(user.getCode(), String.valueOf(yzm))) {
            return Result.error("验证码错误，请输入正确验证码");
        }
        // 解密前端密码
        String pwd = CryptoUtil.desEncrypt(user.getPassword(), sysConf.getCKey(), user.getIv());
        // 处理密码
        Pair<String, String> saltPair = SaltAESUtil.encrypt(pwd);
        user.setPassword(saltPair.getKey()).setSalt(saltPair.getValue()).setIdNumber(idNumber);
        user.setUpdateTime(LocalDateTime.now());
        user.setCreateTime(LocalDateTime.now());
        // 给默认值
        if (user.getGender() == null){
            user.setGender((short) 1);
        }
        if (user.getUserType() == null) {
            user.setUserType((short) 1);
        }
        userMapper.insert(user);
        return Result.success();
    }

    @Log
    @Override
    public Result update(User user) {
        // 查询用户是否存在
        User curUser = userMapper.getByID(user.getUserID());
        if (curUser == null) {
            return Result.error("无法更新，更新用户不存在");
        }
        // 解密身份id
        String idNumber = CryptoUtil.desEncrypt(user.getIdNumber(), sysConf.getCKey(), user.getIv());
        if (StringUtils.isBlank(idNumber)) {
            return Result.error("身份证号无效！");
        }
        user.setIdNumber(idNumber);
        boolean b1 = true;
        boolean b2 = true;
        if(user.getPhoneNumber() != null)
        {
            b1 = CheckUtil.isValidPhoneNumber(user.getPhoneNumber());
        }
        if(user.getIdNumber() != null)
        {
            b2 = CheckUtil.isValidIdCard(user.getIdNumber());
        }
        if(!(b1&&b2)){
            return Result.error("身份证或手机号码错误");
        }
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
        return Result.success();
    }

    @Override
    public Result updatePwd(User user) {
        // 查询用户是否存在
        User curUser = userMapper.getByID(user.getUserID());
        if (curUser == null) {
            return Result.error("无法更新，更新用户不存在");
        }
        // 解密
        String password = CryptoUtil.desEncrypt(user.getPassword(), sysConf.getCKey(), user.getIv());
        if (StringUtils.isBlank(password)) {
            return Result.error("密码无效！");
        }
        // 处理密码
        Pair<String, String> saltPair = SaltAESUtil.encrypt(password);
        user.setPassword(saltPair.getKey()).setSalt(saltPair.getValue());
        user.setUpdateTime(LocalDateTime.now());
        // 更新密码
        userMapper.update(user);
        return Result.success();
    }

    @Override
    public PageBean page(Integer page, Integer pageSize, String name,
                         Short gender,Short userType, LocalDate begin, LocalDate end) {
        //1.设置分页参数
        PageHelper.startPage(page,pageSize);
        //2.执行查询
        List<User> userList = userMapper.list(name,gender,userType,begin,end);
        Page<User> p = (Page<User>) userList;
        //3.封装PageBean对象
        PageBean pageBean = new PageBean(p.getTotal(),p.getResult());

        return pageBean;
    }

    @Override
    public User login(User user) {
        //调用dao层功能：登录
        User loginUser = userMapper.getByUsername(user);
        if (loginUser == null) {
            return null;
        }
        String realPwd = SaltAESUtil.decrypt(loginUser.getSalt(), loginUser.getPassword());
        // 解密前端密码
        String pwd = CryptoUtil.desEncrypt(user.getPassword(), sysConf.getCKey(), user.getIv());
        // 密码比对
        if (StringUtils.equals(realPwd, pwd)) {
            return loginUser;
        }
        //返回查询结果给Controller
        return null;
    }

    @Override
    public Boolean isExistUserName(String userName) {
        int existUserName = userMapper.isExistUserName(userName);
        return existUserName == 0;
    }
}
